import tkinter as tk
from tkinter import filedialog, messagebox
import struct

def crear_tap(nombre_binario, nombre_tap, direccion_carga=60000):
    try:
        with open(nombre_binario, "rb") as f:
            datos = f.read()

        nombre_bloque = "CODE"  # Nombre visible del bloque
        longitud_datos = len(datos)

        # Crear cabecera
        cabecera = bytes([
            0x00,  # Flag para cabecera
            0x03,  # Tipo: CODE
            *nombre_bloque.ljust(10).encode('ascii'),  # Nombre de 10 caracteres
            longitud_datos & 0xFF, (longitud_datos >> 8) & 0xFF,  # Tamaño de datos
            direccion_carga & 0xFF, (direccion_carga >> 8) & 0xFF,  # Dirección de carga
            0x00, 0x80  # Longitud de variables y flag especial
        ])

        checksum_cabecera = 0
        for b in cabecera[1:]:
            checksum_cabecera ^= b

        bloque_cabecera = struct.pack('<H', len(cabecera) + 1) + cabecera + bytes([checksum_cabecera])

        # Crear datos
        bloque_datos = bytes([0xFF]) + datos
        checksum_datos = 0xFF
        for b in datos:
            checksum_datos ^= b

        bloque_datos += bytes([checksum_datos])
        bloque_datos = struct.pack('<H', len(bloque_datos)) + bloque_datos

        with open(nombre_tap, "wb") as f:
            f.write(bloque_cabecera)
            f.write(bloque_datos)

        return True

    except Exception as e:
        messagebox.showerror("Error", f"No se pudo crear el archivo TAP:\n{e}")
        return False

def seleccionar_binario():
    nombre = filedialog.askopenfilename(title="Seleccionar archivo BIN", filetypes=[("Archivos binarios", "*.bin")])
    if nombre:
        entrada_var.set(nombre)

def seleccionar_salida():
    nombre = filedialog.asksaveasfilename(title="Guardar archivo TAP como", defaultextension=".tap", filetypes=[("Archivos TAP", "*.tap")])
    if nombre:
        salida_var.set(nombre)

def generar_tap():
    archivo_entrada = entrada_var.get()
    archivo_salida = salida_var.get()
    if not archivo_entrada or not archivo_salida:
        messagebox.showwarning("Faltan datos", "Debes seleccionar el archivo BIN de entrada y el archivo TAP de salida.")
        return

    if crear_tap(archivo_entrada, archivo_salida):
        messagebox.showinfo("Éxito", f"Archivo TAP generado:\n{archivo_salida}")

# --- Interfaz gráfica ---
root = tk.Tk()
root.title("Generador de TAP desde BIN")

entrada_var = tk.StringVar()
salida_var = tk.StringVar()

tk.Label(root, text="Archivo BIN de entrada:").grid(row=0, column=0, sticky="e")
tk.Entry(root, textvariable=entrada_var, width=50).grid(row=0, column=1)
tk.Button(root, text="Buscar...", command=seleccionar_binario).grid(row=0, column=2)

tk.Label(root, text="Archivo TAP de salida:").grid(row=1, column=0, sticky="e")
tk.Entry(root, textvariable=salida_var, width=50).grid(row=1, column=1)
tk.Button(root, text="Seleccionar...", command=seleccionar_salida).grid(row=1, column=2)

tk.Button(root, text="Generar TAP", command=generar_tap, bg="green", fg="white").grid(row=2, column=0, columnspan=3, pady=10)

root.mainloop()
